#include "StdAfx.h"
#include "ImageRevise.h"
#include "ImageMan.h"

ImageRevise::ImageRevise(void)
{
	m_nWidth  = 0;    
	m_nHeight = 0;   

	m_pfReviseK1 = NULL;
	m_pfReviseK2 = NULL;

	m_bReviseImage     = FALSE;
	m_bOldReviseImage  = FALSE;

	m_dwGray = 0x100;

	m_nRevWidth  = 0;
	m_nRevHeight = 0;

	m_nDataMaxSize = 0;
	m_nDataMinSize = 0;

	m_pwDataMax  = NULL;
	m_pwDataMin  = NULL;
}

ImageRevise::~ImageRevise(void)
{
	DD_AUTO_LOCK xLock(&m_ReviseSect);

	m_nWidth  = 0;    
	m_nHeight = 0; 

	MySafeDeleteMAB(m_pfReviseK1);
	MySafeDeleteMAB(m_pfReviseK1);

	UnInitReviseData();
}


int ImageRevise::SelectReviseFile(char *pFile,int nCreateRevise)
{
	if( NULL == pFile )return -1;

	m_nWidth  = 0;    
	m_nHeight = 0; 

	int nRet = -1;

	m_bReviseImage = FALSE;

	do 
	{
		DDReadWriteFile xFile;

		if( 0 != xFile.DDCreateFile(pFile) )
		{
			nRet = -1;
			break;
		}

		nRet = xFile.DDOperatorFile( (BYTE*)&m_xSysResviseFile,sizeof(zkReviseFileInfo) );
		if( nRet != 0)
		{
			break;
		}

		if( memcmp(m_xSysResviseFile.szPlugDesc, ( (ImageMan*)this )->m_xUseDevDesc.cDeviceName,DDDEVNAMELEN) != 0 )
		{
			break;
		}

		UnInitReviseData();

		m_nWidth  = m_xSysResviseFile.nWidth; 
		m_nHeight = m_xSysResviseFile.nHeight;

//dkq 2013-01-02
		m_dwGray = 65535;
///////////////////////////////////////

		int nSize = m_nWidth * m_nHeight;

		if( m_nDataMinSize < nSize )
		{
			m_nDataMinSize = nSize;
			MySafeDeleteMAB(m_pwDataMin);

			m_pwDataMin = new WORD[m_nDataMinSize+10];
			if( NULL == m_pwDataMin )
			{
				return -1;
			}
			nRet = xFile.DDOperatorFile( (BYTE*)m_pwDataMin,sizeof(WORD)*nSize);
			if( nRet != 0)
			{
				break;
			}
		}

		if( m_nDataMaxSize < nSize )
		{
			m_nDataMaxSize = nSize;
			MySafeDeleteMAB(m_pwDataMax);

			m_pwDataMax = new WORD[nSize+10];
			if( NULL == m_pwDataMax )
			{
				return -1;
			}
			nRet = xFile.DDOperatorFile( (BYTE*)m_pwDataMax,sizeof(WORD)*nSize);
			if( nRet != 0)
			{
				break;
			}
		}

// 		if( nCreateRevise == 0 )
// 		{
// 			m_nDataMinSize = 0;
// 			MySafeDeleteMAB(m_pwDataMin);
// 		}
		
		nRet = CreateReviseParam();

// 		if( nCreateRevise == 0 )
// 		{
// 			nRet = 0;
// 		}

	}while(false);

	return nRet;
}


int ImageRevise::CreateReviseParam()
{
	DD_AUTO_LOCK xLock(&m_ReviseSect);

	int nRet = -1;

	float *pK1=NULL,*pK2=NULL;

	MySafeDeleteMAB(m_pfReviseK1);
	MySafeDeleteMAB(m_pfReviseK2);

	do 
	{
		if( NULL == m_pwDataMax )
		{
			break;
		}
		if( NULL == m_pwDataMin )
		{
            SetGradeOne( &m_xReviseBitInfo );

			if( NULL == m_pwDataMin ||
				m_nRevWidth != m_xSysResviseFile.nWidth ||
				m_nRevHeight != m_xSysResviseFile.nHeight )
			{
               break;
			}
		}

		m_nRevWidth  = m_xSysResviseFile.nWidth; 
		m_nRevHeight = m_xSysResviseFile.nHeight;

		int nSize = m_nWidth * m_nHeight;

		pK1 = new float[nSize+10];
		pK2 = new float[nSize+10];
		if( NULL == pK1 || NULL == pK1)
		{
			break;
		}

		float fGray = (float)m_dwGray;

		int nTmp = 0;
		int nOffset = 0;
		for(int i=0;i<m_nRevHeight;i++)
		{
			for(int j=0;j<m_nRevWidth;j++)
			{
				nOffset  = i*m_nRevWidth+j;

				fGray = (float)m_dwGray;
				nTmp = m_pwDataMax[nOffset] - m_pwDataMin[nOffset];
				if( nTmp == 0 )
				{
					fGray = 1;

					pK1[nOffset] = fGray;
					pK2[nOffset] = fGray * m_pwDataMin[nOffset];
				}
				else if( nTmp > 0 )
				{
					fGray /= nTmp;

					pK1[nOffset] = fGray;
					pK2[nOffset] = fGray * m_pwDataMin[nOffset];
				}
				else 
				{
					nTmp *= -1;
					fGray /= nTmp;

					pK1[nOffset] = fGray;
					pK2[nOffset] = fGray * m_pwDataMax[nOffset];
				}	
			}
		}

		m_pfReviseK1 = pK1;
		m_pfReviseK2 = pK2;

		m_bReviseImage = TRUE;

		UnInitReviseData();

		return 0;

	}while(false);

	MySafeDeleteMAB(pK1);
	MySafeDeleteMAB(pK2);

	return nRet;
}

int ImageRevise::Revise(zkImgBitInfo *pImgBitInfo)
{
	if( !m_bReviseImage ) return -1;
	if( NULL == pImgBitInfo ) return -1;

	DD_AUTO_LOCK xLock(&m_ReviseSect);

	if( NULL == m_pfReviseK1  || NULL == m_pfReviseK2 )return -1;

	switch( pImgBitInfo->nImgDefine ) 
	{
	case eImage_Define_Img8:
		{

		}
		break;
	case eImage_Define_Img16:
		{
			int nWidth  = pImgBitInfo->nWidth;
			int nHeight = pImgBitInfo->nHeight;
			
			if( nWidth != m_nWidth || nHeight != m_nHeight )
			{
				return -1;
			}

			float *pK1 = m_pfReviseK1;
			float *pK2 = m_pfReviseK2;

			WORD *pData =  (WORD*)pImgBitInfo->pImageData;

			int   nOffset   = 0;
			int   nMaxValue = 1<<pImgBitInfo->nBitPerSample;
			nMaxValue -= 1;
			float fValue = 0;
			int   nValue = 0;
			for(int i=0;i<nHeight;i++)
			{
				for(int j=0;j<nWidth;j++)
				{
					nOffset = i*nWidth+j;

					fValue = *( pData+nOffset );
					fValue = fValue * pK1[nOffset] - pK2[nOffset];

					nValue = (int)fValue;
					if( nValue > nMaxValue )
					{
						pData[nOffset] = nMaxValue;
					}
					else if( nValue < 0 )
					{
						pData[nOffset] = 0;
					}
					else
					{
						pData[nOffset] = nValue;
					}
				}
			}
		}
		break;
	case eImage_Define_Img32:
		{
		}
		break;
	default:
		break;
	}


	return 0;
}

int ImageRevise::ReviseNegative(zkImgBitInfo *pImgBitInfo)
{
	switch( pImgBitInfo->nImgDefine ) 
	{
	case eImage_Define_Img8:
		{

		}
		break;
	case eImage_Define_Img16:
		{
			int nWidth  = pImgBitInfo->nWidth;
			int nHeight = pImgBitInfo->nHeight;

			if( nWidth != m_nWidth || nHeight != m_nHeight )
			{
				return -1;
			}

			float *pK1 = m_pfReviseK1;
			float *pK2 = m_pfReviseK2;

			WORD *pData =  (WORD*)pImgBitInfo->pImageData;

			int   nOffset   = 0;
			int   nMaxValue = 1<<pImgBitInfo->nBitPerSample;
			nMaxValue -= 1;
			float fValue = 0;
			int   nValue = 0;
			for(int i=0;i<nHeight;i++)
			{
				for(int j=0;j<nWidth;j++)
				{
					nOffset = i*nWidth+j;

					fValue = *( pData+nOffset );
					fValue = fValue * pK1[nOffset] - pK2[nOffset];

					nValue = (int)fValue;
					if( nValue > nMaxValue )
					{
						pData[nOffset] = 0;
					}
					else if( nValue < 0 )
					{
						pData[nOffset] = nMaxValue;
					}
					else
					{
						pData[nOffset] = nMaxValue - nValue;
					}
				}
			}
		}
		break;
	case eImage_Define_Img32:
		{
		}
		break;
	default:
		break;
	}

	return 0;
}


int ImageRevise::SetFirstFrame(zkImgBitInfo *pImgBitInfo)
{
	switch( pImgBitInfo->nImgDefine ) 
	{
	case eImage_Define_Img8:
		{
			
		}
		break;
	case eImage_Define_Img16:
		{
			m_xReviseBitInfo.nImgDefine     = pImgBitInfo->nImgDefine    ;  
			m_xReviseBitInfo.nBitPerSample  = pImgBitInfo->nBitPerSample ;
			m_xReviseBitInfo.nSapPerPixel   = pImgBitInfo->nSapPerPixel  ; 
			m_xReviseBitInfo.nExistMinus    = pImgBitInfo->nExistMinus   ;  
			m_xReviseBitInfo.nWidth         = pImgBitInfo->nWidth        ;
			m_xReviseBitInfo.nHeight        = pImgBitInfo->nHeight       ;   
			m_xReviseBitInfo.bAutoDelete    = FALSE; 

			int nSize = sizeof(WORD)*pImgBitInfo->nWidth*pImgBitInfo->nHeight;
			if( !m_xReviseBuffer.Allocate(nSize) )
			{
               return -1;
			}
			memcpy( m_xReviseBuffer.pBuffer,pImgBitInfo->pImageData,nSize);
			m_xReviseBitInfo.pImageData     = m_xReviseBuffer.pBuffer;   
		}
		break;
	case eImage_Define_Img32:
		{
		}
		break;
	default:
		break;
	} 

	CreateReviseParam();

	return 0;
}

void ImageRevise::InitReviseData()
{
}

void ImageRevise::UnInitReviseData()
{
	m_nRevWidth  = 0;
	m_nRevHeight = 0;
	m_nDataMaxSize = 0;
	m_nDataMinSize = 0;
	MySafeDeleteMAB(m_pwDataMin);
	MySafeDeleteMAB(m_pwDataMax);
}

int ImageRevise::StartRevise()
{
	UnInitReviseData();

	return 0;
}

int ImageRevise::SetGradeOne(zkImgBitInfo *pImgBitInfo)
{
	if( NULL == pImgBitInfo ) return -1;

	switch( pImgBitInfo->nImgDefine ) 
	{
	case eImage_Define_Img8:
		{
			
		}
		break;
	case eImage_Define_Img16:
		{
			int nWidth  = pImgBitInfo->nWidth;
			int nHeight = pImgBitInfo->nHeight;
			m_nRevWidth  = nWidth;
			m_nRevHeight = nHeight;

			int nSize = nWidth * nHeight;
			if( m_nDataMinSize < nSize )
			{
				m_nDataMinSize = nSize;
				MySafeDeleteMAB(m_pwDataMin);

				m_pwDataMin = new WORD[nSize+10];
			}
			if( NULL == m_pwDataMin )
			{
				return -1;
			}

			m_dwGray = 1 << pImgBitInfo->nBitPerSample;

			memcpy( m_pwDataMin, pImgBitInfo->pImageData,nSize*sizeof(WORD) );
		}
		break;
	case eImage_Define_Img32:
		{
		}
		break;
	default:
		break;
	}


	return 0;
}

int ImageRevise::SetGradeTwo(zkImgBitInfo *pImgBitInfo)
{
	if( NULL == pImgBitInfo ) return -1;

	switch( pImgBitInfo->nImgDefine ) 
	{
	case eImage_Define_Img8:
		{

		}
		break;
	case eImage_Define_Img16:
		{
			int nWidth  = pImgBitInfo->nWidth;
			int nHeight = pImgBitInfo->nHeight;

			if( m_nRevWidth != nWidth || m_nRevHeight != nHeight )
			{
				return -1;
			}

			int nSize = nWidth * nHeight;
			if( m_nDataMaxSize < nSize )
			{
				m_nDataMaxSize = nSize;
				MySafeDeleteMAB(m_pwDataMax);

				m_pwDataMax = new WORD[nSize+10];
			}
			if( NULL == m_pwDataMax )
			{
				return -1;
			}

			memcpy( m_pwDataMax, pImgBitInfo->pImageData,nSize*sizeof(WORD) );
		}
		break;
	case eImage_Define_Img32:
		{
		}
		break;
	default:
		break;
	}

	return 0;
}

int ImageRevise::SaveReviseFile(char *pFileName)
{
	if( NULL == pFileName )
	{
		return -1;
	}

	int nRet = -1;

	do 
	{
		if( NULL == m_pwDataMax )
		{
			nRet = DD_ERR_NOTSETHIGHVOLTAGE;
			break;
		}

		int nSize = m_nRevWidth * m_nRevHeight;

		m_xSysResviseFile.nWidth  = m_nRevWidth;
		m_xSysResviseFile.nHeight = m_nRevHeight;

		DDReadWriteFile xFile;

		if( 0 != xFile.DDCreateFile(pFileName,FALSE) )
		{
			nRet = -1;
			break;
		}

    	sprintf( m_xSysResviseFile.szPlugDesc, ( (ImageMan*)this )->m_xUseDevDesc.cDeviceName ); 

		nRet = xFile.DDOperatorFile( (BYTE*)&m_xSysResviseFile,sizeof(zkReviseFileInfo),NULL,FALSE);
		if( nRet != 0)
		{
			break;
		}
        
		if( NULL != m_pwDataMin )
		{
			nRet = xFile.DDOperatorFile( (BYTE*)m_pwDataMin,sizeof(WORD)*nSize,NULL,FALSE);
			if( nRet != 0)
			{
				break;
			}
		}

		nRet = xFile.DDOperatorFile( (BYTE*)m_pwDataMax,sizeof(WORD)*nSize,NULL,FALSE);
		if( nRet != 0)
		{
			break;
		}

		UnInitReviseData();

	}while(false);

	return nRet;
}
